package cool.taomu.toolkit.service.kademlia.utils

import java.io.OutputStream
import java.util.function.Function
import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtend.lib.annotations.ToString
import org.slf4j.LoggerFactory

class FileDownloadUtils {
    val static LOG = LoggerFactory.getLogger(FileDownloadUtils);

    @Accessors
    @ToString
    static class FileInfo {
        String infoHash;
        long offset;
        long readLength;
        int piecesHashIndex = 0

        new(String infoHash, long offset, long readLength, int piecesIndex) {
            this.infoHash = infoHash
            this.offset = offset
            this.readLength = readLength
            this.piecesHashIndex = piecesIndex;
        }
    }

    def boolean download(String infoHash, OutputStream out, Function<String, Long> getFileSize,
        Function<FileInfo, byte[]> pieces) {
        var long pieceLength = 262144L;
        return this.download(infoHash, pieceLength, out, getFileSize, pieces)
    }

    def boolean download(String infoHash, long pieceLength, OutputStream out, Function<String, Long> getFileSize,
        Function<FileInfo, byte[]> pieces) {
        var long fileSize = getFileSize.apply(infoHash);
        LOG.info("开始下载，总大小: " + fileSize + " bytes");

        for (var long offset = 0, var int index = 0; offset < fileSize; offset += pieceLength, index++) {
            var long remaining = fileSize - offset;
            var long readLength = Math.min(pieceLength, remaining);
            var fileInfo = new FileInfo(infoHash, offset, readLength, index);
            LOG.debug("File Info:{}", fileInfo);
            var byte[] data = pieces.apply(fileInfo);
            if (data.size > 0) {
                out.write(data);
                LOG.info("已下载 {} / {} 字节", offset + data.length, fileSize);
            } else {
                LOG.info("获取到的byte[]大小为0")
                return false;
            }
        }
        return true;
    }
}
